home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGNG_C
/
CFLOW.LZH
/
FILEWDIR.C
< prev
next >
Wrap
Text File
|
1985-06-24
|
6KB
|
222 lines
/* filewdir.c CI-C86 Utility Function
Copyright (c) 1985 by:
Lawrence R. Steeger
1009 North Jackson Street
Milwaukee, Wisconsin 53202
414-277-8149
*/
#include <stdio.h>
typedef struct _files {
struct _files *_fchain, /* next FILES pointer */
*_bchain; /* previous FILES pointer */
unsigned int _fmode; /* original "mode" */
unsigned char *_fspec, /* original "filespec" */
*_file1, /* 1st file name */
*_fnext; /* next file name */
} FILES;
#define fchain fcurr->_fchain
#define bchain fcurr->_bchain
#define fmode fcurr->_fmode
#define fspec fcurr->_fspec
#define file1 fcurr->_file1
#define fnext fcurr->_fnext
static FILES *fanchor = NULL; /* FILES anchor pointer */
/* filewdir(filespec,mode)
Return file name specifications that match a wildcard "filespec"
in the specified "mode".
Returns: (unsigned char *) 1st or next file name specification
NULL no more file name specifications
Note: File name specifications returned may be freed
by using free().
To reset all file specifications in progress
use "filewdir("")". Any currently active
"filespec"s will be purged.
Legal file modes are:
0x00 Normal
0x01 Read Only
0x02 Hidden
0x04 System
0x08 Volume Label
0x10 Subdirectory
0x20 Archive
*/
unsigned char *filewdir(filespec, mode)
unsigned char *filespec;
unsigned int mode;
{
unsigned char *filedir(); /* standard CI-C86 "dir" function */
char *alloc(), /* standard function */
*strcpy(); /* standard function */
register FILES *fcurr, /* FILES current entry pointer */
*ftemp; /* FILES temporary pointer */
unsigned char *fileptr; /* file name specification pointer */
if (*filespec == '\0') { /* purge all FILES */
for (fcurr = fanchor; fcurr != NULL;) { /* run FILES chain */
ftemp = fchain;
/* free a FILES entry */
free(fspec);
free(file1);
free((unsigned char *)fcurr);
fcurr = ftemp;
}
return (unsigned char *)(fanchor = NULL);
}
/* search FILES for matching file specification and file mode */
for (fcurr = ftemp = fanchor;
fcurr != NULL;
ftemp = fcurr, fcurr = fchain)
if ((strcmp(fspec, filespec) == 0)
&& (mode == fmode))
break;
if (fcurr != NULL) { /* existing entry found... */
if (*fnext) { /* ...and a file name exists */
fileptr = alloc((strlen(fnext) + 1)); /* file name */
strcpy(fileptr, fnext);
fnext += (strlen(fnext) + 1); /* next file name */
return (fileptr); /* return file name */
}
/* no more file names - dechain this entry and return NULL */
if (bchain == NULL)
fanchor = fchain; /* 1st on chain */
else
bchain->_fchain = fchain; /* not 1st on chain */
/* free this entry */
free(fspec);
free(file1);
free((unsigned char *)fcurr);
return (NULL); /* indicate no files left */
}
/* new FILES entry may be required */
if (*(fileptr = filedir(filespec, mode)) == '\0') {
free(fileptr);
return (NULL); /* no file names */
}
/* at least 1 file name found */
fcurr = alloc(sizeof(FILES)); /* allocate FILES entry */
if (ftemp == NULL)
fanchor = fcurr; /* 1st on chain */
else
ftemp->_fchain = fcurr; /* last on chain */
bchain = ftemp; /* back chain link */
fspec = alloc(strlen(filespec) + 1); /* save file specification */
strcpy(fspec, filespec);
fmode = mode; /* save file mode */
file1 = fnext = fileptr; /* set files' pointers */
fileptr = alloc((strlen(fileptr) + 1)); /* get file name storage */
strcpy(fileptr, fnext);
fnext += (strlen(fnext) + 1); /* next file name pointer */
return (fileptr); /* return 1st file name */
}
/* get file directory
note:
this contains a bypass for the way DOS functions 0x4e and 0x4f
work. this bypass enables true selection by mode.
an extension has been added to "mode". if mode = 0xffff then
all file names matching the filespec will be returned.
*/
unsigned char *realloc();
struct ff_str {
char dummy[21]; /* reserved for dos */
unsigned char attribute; /* returned attribute */
unsigned time;
unsigned date;
long size; /* size of file */
unsigned char fn[13]; /* string containing the filename */
};
unsigned char *filedir(filename,mode)
unsigned char *filename;
unsigned mode;
{
struct {int ax,bx,cx,dx,si,di,ds,es;}srv;
struct ff_str ff_area;
unsigned char *result=0;
int reslen=0;
#ifdef _C86_BIG
srv.ds=((unsigned long)filename)>>16;
#else
segread(&srv.si); /* get ds value */
#endif
srv.dx=filename;
if (mode) srv.cx=0xff; /* set search all modes */
else srv.cx=0x00; /* set search normal only */
bdos(0x1a,&ff_area); /* set the transfer address */
for(srv.ax=0x4e00;!(sysint21(&srv,&srv)&1);srv.ax=0x4f00){
/* printf(":%s 0x%02x:", ff_area.fn, ff_area.attribute); */
if ((mode && !(ff_area.attribute & (unsigned char)mode))
&& (mode != 0xffff)) {
/* printf("\n"); */
continue;
}
/* return only filenames with desired modes */
result=realloc(result,reslen+strlen(ff_area.fn)+1);
if (result==NULL) return NULL; /* no memory left */
strcpy(result+reslen,ff_area.fn);
reslen+=strlen(ff_area.fn)+1;
/* printf("<\n"); */
}
return realloc(result,reslen+1);
}
/* end of filewdir.c */